package com.dlc.shop.api.controller;


import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.dlc.shop.bean.app.dto.UserCollectionDto;
import com.dlc.shop.bean.enums.ProdType;
import com.dlc.shop.bean.model.Product;
import com.dlc.shop.bean.model.UserCollection;
import com.dlc.shop.bean.model.UserCollectionShop;
import com.dlc.shop.bean.vo.search.EsProductSearchVO;
import com.dlc.shop.common.exception.YamiShopBindException;
import com.dlc.shop.common.response.ServerResponseEntity;
import com.dlc.shop.common.util.PageParam;
import com.dlc.shop.security.api.util.SecurityUtils;
import com.dlc.shop.service.BasketService;
import com.dlc.shop.service.ProductService;
import com.dlc.shop.service.UserCollectionService;
import com.dlc.shop.service.UserCollectionShopService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Parameters;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.AllArgsConstructor;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.web.bind.annotation.*;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @author LGH
 */
@RestController
@RequestMapping("/p/user/collection")
@Tag(name = "商品收藏接口")
@AllArgsConstructor
public class UserCollectionController {

    private final UserCollectionService userCollectionService;
    private final UserCollectionShopService userCollectionShopService;

    private final BasketService basketService;

    private final ProductService productService;

    @GetMapping("/page")
    @Operation(summary = "分页返回收藏数据" , description = "根据用户id获取")
    @Parameters({
            @Parameter(name = "prodName", description = "商品名称" , required = true),
            @Parameter(name = "prodType", description = "商品类型" , required = true)
    })
    public ServerResponseEntity<IPage<UserCollectionDto>> getUserCollectionDtoPageByUserId(PageParam page, String prodName, Integer prodType) {
        return ServerResponseEntity.success(userCollectionService.getUserCollectionDtoPageByUserId(page, SecurityUtils.getUser().getUserId(), prodName, prodType));
    }

    @GetMapping("/isCollection")
    @Operation(summary = "根据商品id获取该商品是否在收藏夹中" , description = "传入收藏商品id")
    @Parameter(name = "prodId", description = "商品id" , required = true)
    public ServerResponseEntity<Boolean> isCollection(String prodId) {
        String[] prodIds = prodId.split(StrUtil.COMMA);
        if (ArrayUtil.isEmpty(prodId)) {
            throw new YamiShopBindException("商品id不能为空");
        }
        int count = 0;
        for (String pLong : prodIds) {
            if (productService.count(new LambdaQueryWrapper<Product>()
                    .eq(Product::getProdId, pLong)) < 1) {
                // 该商品不存在
                throw new YamiShopBindException("yami.product.no.exist");
            }
            long i = userCollectionService.count(new LambdaQueryWrapper<UserCollection>()
                    .eq(UserCollection::getProdId, pLong)
                    .eq(UserCollection::getUserId, SecurityUtils.getUser().getUserId()));
            count += i;
        }
        return ServerResponseEntity.success(count == prodIds.length);
    }

    @PostMapping("/addOrCancel")
    @Operation(summary = "添加/取消收藏" , description = "传入收藏商品id,如果商品未收藏则收藏商品，已收藏则取消收藏")
    @Parameter(name = "prodId", description = "商品id" , required = true)
    public ServerResponseEntity<Boolean> addOrCancel(@RequestBody Long prodId) {
        Product product = productService.getProductByProdId(prodId);
        if (Objects.isNull(product)) {
            // 该商品不存在
            throw new YamiShopBindException("yami.product.no.exist");
        }
        boolean isAdd = false;
        String userId = SecurityUtils.getUser().getUserId();
        //pc端收藏商品时，清除购物车缓存
        basketService.removeCacheByUserIds(Collections.singletonList(userId));
        if (userCollectionService.count(new LambdaQueryWrapper<UserCollection>()
                .eq(UserCollection::getProdId, prodId)
                .eq(UserCollection::getUserId, userId)) > 0) {
            userCollectionService.remove(new LambdaQueryWrapper<UserCollection>()
                    .eq(UserCollection::getProdId, prodId)
                    .eq(UserCollection::getUserId, userId));
        } else {
            if (Objects.equals(product.getProdType(), ProdType.PROD_TYPE_ACTIVE.value())) {
                // 组合选品不能添加收藏
                throw new YamiShopBindException("yami.active.prod.cannot.add.collection");
            }
            UserCollection userCollection = new UserCollection();
            userCollection.setCreateTime(new Date());
            userCollection.setUserId(userId);
            userCollection.setProdId(prodId);
            userCollectionService.save(userCollection);
            isAdd = true;
        }
        return ServerResponseEntity.success(isAdd);
    }

    @PostMapping("/batachCancel")
    @Operation(summary = "批量取消收藏" , description = "传入收藏商品id")
    @Parameter(name = "prodIds", description = "商品id" , required = true)
    public ServerResponseEntity<Boolean> batachCancel(@RequestBody List<Long> prodIds) {
        String userId = SecurityUtils.getUser().getUserId();
        if (CollectionUtils.isEmpty(prodIds)) {
            return ServerResponseEntity.success(false);
        }
        boolean remove = false;
        List<Product> products = productService.listByIds(prodIds);
        List<Long> dbProdIdList = products.stream().map(Product::getProdId).toList();
        for (Long prodId : prodIds) {
            if (!dbProdIdList.contains(prodId)) {
                continue;
            }
            long count = userCollectionService.count(new LambdaQueryWrapper<UserCollection>()
                    .eq(UserCollection::getProdId, prodId)
                    .eq(UserCollection::getUserId, userId));
            if (count <= 0) {
                continue;
            }
            remove = userCollectionService.remove(new LambdaQueryWrapper<UserCollection>()
                    .eq(UserCollection::getProdId, prodId)
                    .eq(UserCollection::getUserId, userId));
        }
        return ServerResponseEntity.success(remove);
    }

    @GetMapping("/count")
    @Operation(summary = "查询用户收藏商品数量" , description = "查询用户收藏商品数量")
    public ServerResponseEntity<Long> findProdCollectionCount() {
        String userId = SecurityUtils.getUser().getUserId();
        return ServerResponseEntity.success(userCollectionService.count(new LambdaQueryWrapper<UserCollection>().eq(UserCollection::getUserId, userId)));
    }

    @GetMapping("collectionCount")
    @Operation(summary = "查询用户收藏数量(商品+店铺收藏数量)" , description = "查询用户收藏数量")
    public ServerResponseEntity<Long> userCollectionCount() {
        String userId = SecurityUtils.getUser().getUserId();
        long prodCollectionCount = userCollectionService.count(new LambdaQueryWrapper<UserCollection>().eq(UserCollection::getUserId, userId));
        long shopCollectionCount = userCollectionShopService.count(new LambdaQueryWrapper<UserCollectionShop>().eq(UserCollectionShop::getUserId, userId));
        return ServerResponseEntity.success(prodCollectionCount + shopCollectionCount);
    }

    @GetMapping("/prods")
    @Operation(summary = "获取用户收藏商品列表", description = "获取用户收藏商品列表")
    public ServerResponseEntity<IPage<EsProductSearchVO>> collectionProds(PageParam page) {
        String userId = SecurityUtils.getUser().getUserId();
        IPage<EsProductSearchVO> prodPage  = userCollectionService.collectionProds(page, userId);
        return ServerResponseEntity.success(prodPage);
    }

    @GetMapping("/orderProdCollectionAll")
    @Operation(summary = "订单商品收藏" , description = "传入商品id拼接字符串")
    @Parameters({
            @Parameter(name = "prodIds", description = "商品id" , required = true),
    })
    public ServerResponseEntity<Boolean> orderProdCollectionAll(String prodIds) {
        String userId = SecurityUtils.getUser().getUserId();
        //去重
//        HashSet<String> prodSet = CollUtil.newHashSet(prodIds.split(StrUtil.COMMA));
        List<String> idsList = Arrays.asList(prodIds.split(StrUtil.COMMA));
        List<Product> productList = productService.listByIds(idsList);
        List<Long> prodIdList = productList.stream()
                .filter(product -> !Objects.equals(product.getProdType(), ProdType.PROD_TYPE_ACTIVE.value()))
                .map(Product::getProdId)
                .collect(Collectors.toList());
        if (CollUtil.isNotEmpty(prodIdList)) {
            userCollectionService.orderProdCollectionAll(prodIdList, userId);
        }
        return ServerResponseEntity.success();
    }
}
